package org.googlecode.viewt.core.tools.contants;

import org.apache.velocity.VelocityContext;
import org.googlecode.viewt.core.tools.AbstractVelocityGenerator;
import org.googlecode.viewt.core.tools.contants.types.ConstantDef;
import org.googlecode.viewt.core.tools.contants.types.Constants;

public class ResourceGenerator extends AbstractVelocityGenerator {
	public static final String CONTEXT_PROP_UTIL = "UTILITY";
	public static final String CONTEXT_PROP_GENERATOR = "GENERATOR";
	public static final String CONTEXT_PROP_PRJNAME = "PROJECT";
	public static final String CONTEXT_PROP_MODNAME = "MODULE";
	public static final String CONTEXT_PROP_CURCONSTANTDEF = "CURRENTCONSTANT";
	public static final String CONTEXT_PROP_CURLOCALE = "CURRENTLOCALE";
	public static final String RESOURCE_TEMPLATE = "properties_RES.vm";
	private Constants constantsDef;
	private String destPath;
	private String fileTemplatePath;
	private String curEncoding;

	public ResourceGenerator() {
		this.constantsDef = null;

		this.destPath = null;

		this.fileTemplatePath = null;

		this.curEncoding = null;
	}

	public void setInitEnv(Constants constantsDef, String destPath)
			throws Exception {
		setConstantsDef(constantsDef);
		setDestPath(destPath);
	}

	public void performGen() throws Exception {
		if ((this.constantsDef == null) || (this.destPath == null)) {
			getLogger()
					.error(
							"Perform generation fail, set config and destination first");
			throw new Exception("config or enviroment not set");
		}

		VelocityContext context = getContext();
		if (null == context) {
			context = new VelocityContext();
			setContext(context);
		}
		context.put("UTILITY", new ConstantUtil());
		context.put("GENERATOR", this);
		context.put("PROJECT", this.constantsDef.getProjectName());
		context.put("MODULE", this.constantsDef.getModuleName());

		String[] encodings = ConstantUtil.outputEncodings(this.constantsDef);
		int size = (null == encodings) ? 0 : encodings.length;
		for (int i = 0; i < size; ++i) {
			this.curEncoding = encodings[i];
			super.init();

			ConstantDef[] constants = ConstantUtil.constantsByEncoding(
					this.curEncoding, this.constantsDef);
			int len = (null == constants) ? 0 : constants.length;
			for (int j = 0; j < len; ++j) {
				ConstantDef constant = constants[j];
				String className = constant.getClassName();
				String[] locales = ConstantUtil.localesByEncoding(
						this.curEncoding, constant);

				int count = (null == locales) ? 0 : locales.length;
				for (int k = 0; k < count; ++k) {
					String locale = locales[k];
					String outputFile = ConstantUtil.resourceFile(
							this.destPath, className, locale);

					if ((null == outputFile) || ("".equals(outputFile))) {
						getLogger().error(
								"Empty output file:" + outputFile
										+ ", generation fail");
						throw new Exception("Empty output file:" + outputFile
								+ ", generation fail");
					}
					context.put("CURRENTCONSTANT", constant);
					context.put("CURRENTLOCALE", locale);

					singleOutput("properties_RES.vm", outputFile);

					context.remove("CURRENTLOCALE");
					context.remove("CURRENTCONSTANT");

					getLogger().debug(
							"generate resource for class:" + className
									+ " under locale:" + locale + " succeed");
				}
			}

		}

		context.remove("MODULE");
		context.remove("PROJECT");
		context.remove("GENERATOR");
		context.remove("UTILITY");

		getLogger().debug("Perform code generation done.");
	}

	public void setConstantsDef(Constants constantsDef) {
		this.constantsDef = constantsDef;
	}

	public Constants getConstantsDef() {
		return this.constantsDef;
	}

	public void setDestPath(String destPath) {
		this.destPath = destPath;
	}

	public String getDestPath() {
		return this.destPath;
	}

	public void setFileTemplatePath(String fileTemplatePath) {
		this.fileTemplatePath = fileTemplatePath;
	}

	public String getFileTemplatePath() {
		return this.fileTemplatePath;
	}

	public String getPackageTemplatePath() {
		return "resource/template/constant";
	}

	public String getOutputEncoding() {
		return this.curEncoding;
	}

	public String getLoggerCategory() {
		return "ResourceGenerator";
	}
}